package signalprocessing;

import ikelib.DelayThreadInterface;
import ikelib.IntegrateAccelaration;
import ikelib.Median;
import ikelib.PlotColor;
import ikelib.wintime;
import ikeuilib.JButtonWithMenu;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.ListSelectionModel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import java.awt.FlowLayout;
import javax.swing.border.EmptyBorder;

import wcg.SignalProcessingInterface;
import wcg.stateChangeNotify;

/**
 * 
 */

/**
 * オフセット　ｖｓ　温度 のｘｙプロットを表示する
 * @author ikechan
 *
 */
public class PanelTemperature extends SignalProcessingPanelBasic implements stateChangeNotify,SignalProcessingInterface, DelayThreadInterface ,PlotPanelCollectionInterface
					,PanelControlYScaleInterface,PanelControlXScaleInterface,SignalprocessingPanelInterface {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JList ListChannel;
	protected PlotPaneCollection PlotCollection=null;

	private JTextField textFieldXChannel;
	protected JCheckBox cbShowDigit;

	/**
	 * 
	 */
	public PanelTemperature() {
		//super();
		setLayout(new BorderLayout(0, 0));
		setPreferredSize(new Dimension(500,500));

		JPanel panelIntegration = new JPanel();
		add(panelIntegration, BorderLayout.CENTER);
		panelIntegration.setLayout(new BorderLayout(0, 0));

		JPanel panelControlPanelIntegration = new JPanel();
		panelIntegration.add(panelControlPanelIntegration, BorderLayout.WEST);

		panelControlPanelIntegration.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		panelControlPanelIntegration.setLayout(null);
		panelControlPanelIntegration.setPreferredSize(new Dimension(210, 600));

		JPanel panelChannelandCalc = new JPanel();
		panelChannelandCalc.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Channel", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
		panelChannelandCalc.setBounds(7, 10, 189, 163);
		panelControlPanelIntegration.add(panelChannelandCalc);
		panelChannelandCalc.setLayout(null);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(12, 38, 67, 115);
		panelChannelandCalc.add(scrollPane);

		ListChannel = new JList();
		scrollPane.setViewportView(ListChannel);
		ListChannel.addListSelectionListener(new ListSelectionListener() {
			// ＣＨセレクションが変更されたとき
			public void valueChanged(ListSelectionEvent arg0) {
				if(!arg0.getValueIsAdjusting()){
					onConfChange();
				}
			}

		});

		textFieldXChannel = new JTextField();
		textFieldXChannel.setText("fffe");
		textFieldXChannel.setBounds(91, 38, 58, 25);
		panelChannelandCalc.add(textFieldXChannel);
		textFieldXChannel.setColumns(10);

		JLabel lblTemperature = new JLabel("Temperature");
		lblTemperature.setBounds(91, 22, 83, 15);
		panelChannelandCalc.add(lblTemperature);

		/*
		 * Ｙスケールコントロール小パネルを表示する
		 */
		PanelControlYScaleConfiguration confyscale = new PanelControlYScaleConfiguration();
		confyscale.TitleBorder = new String("Y Scale");
		confyscale.SingleButton = true;
		
		PanelControlYScale panelControlYScale = new PanelControlYScale(confyscale);
		panelControlYScale.setLocation(7, 239);
		panelControlYScale.addParent(this);
		panelControlPanelIntegration.add(panelControlYScale);


		/*
		 * Xスケールコントロール小パネルを表示する
		 */
		PanelControlXScaleConfiguration confx  = new PanelControlXScaleConfiguration();
		confx.TitleBorder = new String("X Scale");
		
		confx.SlideP 			= 20;
		confx.SlidePKeyShift 	= 100;
		confx.SlideN 			= -20;
		confx.SlideNKeyShift 	= -100;
		confx.ZoomIn 			= 80;
		confx.ZoomInKeyShift 	= 50;
		confx.ZoomOut 			= 120;
		confx.ZoomOutKeyShift 	= 200;
		
		PanelControlXScale panelControlXScale = new PanelControlXScale(confx);
		panelControlXScale.setLocation(7, 371);
		panelControlXScale.addParent(this);
		panelControlPanelIntegration.add(panelControlXScale);
		
		JPanel panelDisplay = new JPanel();
		panelDisplay.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Display ", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
		panelDisplay.setBounds(10, 178, 185, 58);
		panelControlPanelIntegration.add(panelDisplay);
				panelDisplay.setLayout(null);
				
				cbShowDigit = new JCheckBox("Digit");
				cbShowDigit.setBounds(8, 24, 67, 21);
				cbShowDigit.setSelected(true);
				panelDisplay.add(cbShowDigit);
				cbShowDigit.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						onConfChange();
					}
				});
				cbShowDigit.setToolTipText("Show in Digit or Physical Scale.");
		
				// とりあえず全部を強制的に再描画するボタン　
				JButton btnRepaint = new JButton("ReDraw");
				btnRepaint.setBounds(83, 24, 90, 21);
				panelDisplay.add(btnRepaint);
				btnRepaint.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent arg0) {
						repaintAllComponent();
					}
				});

		
		
		PlotPanelCollectionConfiguration conf = new PlotPanelCollectionConfiguration();
		conf.XAxisGap = 0;
		conf.XAxisType = PlotPanelCollectionConfiguration.XAxisTypeX;
		PlotCollection = new PlotPaneCollection(Col,conf);
		panelIntegration.add(PlotCollection, BorderLayout.CENTER);
		PlotCollection.setUp(this,AccViewCh,Plot,Col);

		{
			//addChannelPanel(0);	// test
		}
		initial();

	}

	/**
	 * チャンネルリストの選択ＣＨ・全ＣＨを得る
	 * @param selected　true=選択ＣＨ、false=全ＣＨ
	 * @return
	 */
	private Integer[] getChannelList(boolean selected){
		if(ListChannel==null) return null;
		ListModel model = ListChannel.getModel(); //@
		int max = model.getSize();
		LinkedList<Integer> lst = new LinkedList<Integer>();
		for(int i=0;i<max;i++){
			boolean disp = ListChannel.isSelectedIndex(i);
			String ms = (String)ListChannel.getModel().getElementAt(i);
			int ch = Integer.valueOf(ms,16);	
			if(selected && disp){
				lst.add(ch);
			}
			else if(!selected){
				lst.add(ch);
			}
		}
		Integer[] ret = lst.toArray(new Integer[0]);
		if(lst.size()<=0) return null;
		return ret;
	}

	/**
	 * CH設定が更新されたとき、コンポーネントを追加削除する
	 */
	public void updateChannel(){
		Integer[] sel2 = getChannelList(true);		// すべてのＣＨ
		Integer[] sel = getChannelList(false); 		// 選択されているＣＨ
		Integer[] subid = getSubId(true); 			// すべてのオプションを得る
		Integer[] subid2 = getSubId(false); 		// 選択されているオプションを得る
		if(PlotCollection != null){
			PlotCollection.onUpdateChannelMultiChannel(sel,sel2,subid2,subid);
			revalidate();
		}
	}
	protected int getXid(){
		int ret = Integer.valueOf(textFieldXChannel.getText(),16);
		return ret;
	}
	protected void onViewChange(){
		setCursor((Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR )));
		repaintAllComponent();
		setCursor((Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR )));
	}
	/**
	 * 計算オプションを表す ＩＤを得る
	 * @return
	 */
	private Integer[] getSubId(boolean getAllOption){
		Integer[] ret = new Integer[1];
		ret[0] = 0;
		return ret; 
	}


	/**
	 * デシメーションする。（単なる間引き）
	 * @param d
	 * @param dec
	 * @return
	 */
	protected double[] decimate(double[] d,int dec){
		if(d==null) return null;
		double[] ret = new double[1+d.length/dec];
		int j=0;
		for(int i=0;i<d.length;i+=dec){
			ret[j++] = d[i];
		}
		return ret;
	}


	protected int DecimationPeriod = 600; // sec
	/**
	 *  1つのＣＨのグラフエリアを生成する。
	 * @param Panel_Channels
	 * @param id
	 */
	protected void addData(Integer[] ids) {

		//	if(subid ==0) return;

		int xid = getXid();
		int sampleratex = getRawSampleRate(xid);
		if(sampleratex<=0) return;
		double[] xdat=getChannelRawData(xid);
		xdat = decimate(xdat,sampleratex*DecimationPeriod);
		LinkedList<String> names = new LinkedList<String>();

		LinkedList<double[]> datas = new LinkedList<double[]>();
		for(int i=0;i<ids.length;i++){
			int id = ids[i];
			int samplerate=getRawSampleRate(id);;
			if(samplerate<=0) return;
			double[] data = null;
			if(cbShowDigit.isSelected()){
				data = getChannelRawData(id,1.0);
			}
			else{
				data = getChannelRawData(id);
			}
			if(data == null || xdat==null){
				//System.out.println("fail to getChannelRawData: SignalProcessingPain " + id + subid);
				String mes=new String("No data found for CH = ");
				if(data == null) mes +=  String.format(" %04x", id);
				if(xdat == null) mes +=  String.format(" %04x", getXid());
				JOptionPane.showMessageDialog(null, "No data found " + mes , mes,  JOptionPane.ERROR_MESSAGE, null);
				return;
			}
			//if(samplerate != 1){
			data = decimate(data,samplerate*DecimationPeriod);
			//}
			datas.add(data);
			String name = new String(String.format("%04X", id));
			names.add(name);
		}
		PlotCollection.addChannelPanel(xid, ids ,names, datas, 1,xdat);
		//addChannelPanel(Panel_Channels,xid, ids ,names, datas, 1,xdat);
	}

	
	/**
	 * ＣＨリストをセットする
	 */
	public void doGetChannel(){
		ListChannel.removeAll();
		DefaultListModel model = new DefaultListModel(); //@
		//Iterator<Integer> ite = Data.getChannel().iterator();
		Iterator<Integer> ite = Data.iteratorChannel();
		while(ite.hasNext()){
			int ch = ite.next();
			String channel = new String();
			channel=String.format("%01X%01X%01X%01X", (ch>>12)&0xf,(ch>>8)&0xf,(ch>>4)&0xf,(ch>>0)&0xf);
			model.addElement(channel);
		}
		ListChannel.setModel(model);
	}
	private void initial(){
		Col.setColorMode(PlotColor.COLOR_COLOR_BLACK_BACK);
	}
	/* (non-Javadoc)
	 * @see stateChangeNotify#onStateChange(int)
	 */
	@Override
	public void onStateChange(int hint) {

	}


	/**
	 * すべてのコンポーネントを再描画させる。
	 */
	/**
	 * すべてのコンポーネントを再描画させる。
	 */
	@Override
	public void repaintAllComponent(){
		PlotCollection.repaintAllComponent();
	}




	/**
	 * @return
	 */
	public Dimension getPanelViewSize() {
		return PlotCollection.getSize();
		//return panel_TopGraph.getSize();
	}

	/**
	 * @param g
	 */
	public void panelViewprintAll(Graphics2D g) {
		PlotCollection.paintAll(g);
		//panel_TopGraph.printAll(g);
	}

	/**
	 * @param colorColorBlackBack
	 */
	public void setColorMode(int colorColorBlackBack) {
		Col.setColorMode(colorColorBlackBack);

	}

	/* (non-Javadoc)
	 * @see PlotPanelCollectionInterface#onSetData(int, int)
	 */
	@Override
	public boolean onSetData(int id, int subid) {
	// TODO ここまちがい	addChannelPanel(id);
		return true;
	}


	/* (non-Javadoc)
	 * @see PlotPanelCollectionInterface#onInitView(int)
	 */
	@Override
	public boolean onInitView(int hint) {
		doYSpanAuto(PlotPane.ScaleAuto_FITMaxMin);
		doYSpan(150);
		doYSpanTruncate(0);

		Iterator<Integer> ite = AccViewCh.iterator();
		while(ite.hasNext()){
			int ch = ite.next();
			PlotPane ac=Plot.get(ch).AcsView;
			ac.getXAxis();
			ac.getXAxis().setAxisDivide(9,true,4,false);
			ac.getXAxis().setXScaleMaxMin((double)70, (double)-20);
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see ikelib.DelayThreadInterface#onDelayCallback(int)
	 */
	@Override
	public void onDelayCallback(int id) {
		
	}

	/* (non-Javadoc)
	 * @see PlotPanelCollectionInterface#onSetData(java.lang.Integer[])
	 */
	@Override
	public boolean onSetData(Integer[] ids) {
		addData(ids);
		return true;
		
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlYScaleInterface#ySpanTruncate(int)
	 */
	@Override
	public void ySpanTruncate(int digit) {
		doYSpanTruncate(digit);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlYScaleInterface#ySpanSingle(int)
	 */
	@Override
	public void ySpanSingle(int mode) {
		doYSpanSingle(mode);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlYScaleInterface#ySpanAuto(int)
	 */
	@Override
	public void ySpanAuto(int mode) {
		doYSpanAuto(mode);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlYScaleInterface#ySpanShift(int)
	 */
	@Override
	public void ySpanShift(int ratio) {
		doYSpanShift(ratio);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlYScaleInterface#ySpanSingleGroup(int)
	 */
	@Override
	public void ySpanSingleGroup(int mode) {
		//doYSpanSingleGroup(mode);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlYScaleInterface#ySpan(int)
	 */
	@Override
	public void ySpan(int ratio) {
		doYSpan(ratio);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlXScaleInterface#xSpanZoom(int)
	 */
	@Override
	public void xSpanZoom(int ratio) {
		doXSpan(ratio);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlXScaleInterface#xShift(int)
	 */
	@Override
	public void xShift(int ratio) {
		doXShift(ratio);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlXScaleInterface#xSpanFull()
	 */
	@Override
	public void xSpanFull() {
		doXSpanAuto(PlotPane.ScaleAuto_FITMaxMin);
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlXScaleInterface#xSpanTruncate(int)
	 */
	@Override
	public void xSpanTruncate(int mode) {
		doXSpanTruncate(mode);
		
	}

	/* (non-Javadoc)
	 * @see signalprocessing.PanelControlYScaleInterface#ySpan(double, double)
	 */
	@Override
	public void ySpan(double max, double min) {
		doYSpan(max,min);
	}
}
